#include "xdecode.h"
#include "xvideo_view.h"
#include <cstring>
#include <iostream>

using namespace std;
extern "C" { // 指定函数是c语言函数，函数名不包含重载标注
// 引用ffmpeg头文件
#include <libavformat/avformat.h>
}
#ifdef main
#undef main
#endif // !main
#define CERR(no)                                                               \
  if (no != 0) {                                                               \
    PrintErr(no);                                                              \
    return -1;                                                                 \
  }

int main(int argc, char *argv[]) {
  av_log_set_level(AV_LOG_ERROR);
  const char *url = "v1080.mp4";
  AVFormatContext *ic = nullptr;
  int ret = avformat_open_input(&ic, url,
                                nullptr, // 封装器格式，nullptr表示自动探测
                                nullptr); // 参数设置，rtsp需要设置
  CERR(ret);
  ret = avformat_find_stream_info(ic, nullptr);
  CERR(ret);
  // 打印信息，
  av_dump_format(ic, 0, url, false);
  // av_find_best_stream();
  AVStream *as = nullptr;
  AVStream *vs = nullptr;
  for (int i = 0; i < ic->nb_streams; ++i) {
    if (ic->streams[i]->codecpar->codec_type ==
        AVMediaType::AVMEDIA_TYPE_AUDIO) {
      as = ic->streams[i];
      cout << "======音频=======" << endl;
      cout << "sample_rate:" << as->codecpar->sample_rate << endl;
    } else if (ic->streams[i]->codecpar->codec_type ==
               AVMediaType::AVMEDIA_TYPE_VIDEO) {
      vs = ic->streams[i];
      cout << "======视频=======" << endl;
      cout << "width:" << vs->codecpar->width << endl;
      cout << "height:" << vs->codecpar->height << endl;
    }
  }
  // 视频编码器id
  auto video_codec_id = vs->codecpar->codec_id;
  auto video_par = vs->codecpar;
  // 视频编码初始化
  XDecode decode;
  auto decode_c = decode.Create(video_codec_id, false);
  // 解封装的视频编码参数，传统给解码对象
  avcodec_parameters_to_context(decode_c, video_par);
  // 设置到编码器中，线程安全，设置完后decode_c不在外部使用
  decode.set_c(decode_c);
  // 打开解码器
  if (!decode.Open()) {
    cout << "decode Open failed!" << endl;
    return -1;
  }
  auto frame = decode.CreateFrame();
  XVideoView *view = XVideoView::Create(XVideoView::SDL);
  view->Init(video_par->width, video_par->height,
             XVideoView::Format(video_par->format));
  AVPacket pkt;
  for (;;) {
    ret = av_read_frame(ic, &pkt);
    if (ret == AVERROR_EOF) {
      break;
    }
    CERR(ret);
    /*if (vs && pkt.stream_index == vs->index) {
      cout << "视屏" << endl;
    } else */
    if (vs && pkt.stream_index == vs->index) {
      // 解码视频
      if (decode.Send(&pkt))
        while (decode.Receive(frame)) {
          cout << "视频" << frame->pts << " " << flush;
          view->DrawFrame(frame);
        }
    }
    av_packet_unref(&pkt);
    // this_thread::sleep_for(40ms);
  }
  auto frameList = decode.End();
  for (auto f : frameList) {
    view->DrawFrame(f);
    av_frame_free(&f);
  }
  av_frame_free(&frame);
  avformat_close_input(&ic);
  return 0;
}
